home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
kms20src.lha
/
KMSC
/
init.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-24
|
16KB
|
654 lines
/**********************************
* KMS *
**********************************
* ©1992 by BlackMagic Software *
**********************************
* *
**********************************/
#include <KMS/KMS.h>
#include <KMS/KMS_devlib.h>
#include <KMS/KMS_intui.h>
/* A handy macro to access AbsExecBase. */
#define SysBase (*(struct ExecBase **)4L)
Prototype UBYTE OpenLib(VOID);
Prototype UBYTE Identify(VOID);
Prototype UBYTE OpenTimer(VOID);
Prototype UBYTE OpenDisplay(VOID);
Prototype VOID Sense(UBYTE);
Prototype VOID TakeMSem(BOOL);
Prototype VOID DropMSem(VOID);
LONG IsInteractive(BPTR);
/*****************************
* Externe Globale Variablen *
*****************************/
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern STRPTR CmdArgV[];
extern STRPTR MsgHead[];
extern STRPTR MsgInfos[];
extern UMSAccount MyUMSAccount;
extern struct rexxCommandList RCL[];
extern struct rexxCommandList TempRCL[];
extern STRPTR KMSTitle;
/*********************
* Globale Variablen *
*********************/
struct Library *DiskfontBase = NULL;
struct MsgPort *Timer_Port = NULL;
struct timerequest *Time_Request = NULL;
struct DosPacket *InputPacket = NULL;
ULONG TimerSignal, RexxSignal, InputSignal;
TEXT KMSWinTitle[81];
/* Konfiguration */
struct KMSBase *KMSBase = NULL;
struct LocalConfig *KMS_LC = NULL;
/* System-UMS-Account */
UMSUserAccount SysUMSAccount = 0;
/* Name unseres privaten MsgPort */
TEXT RexxPortName[16];
STRPTR RexxExtension = "KMS";
/* Temp-Dateiname */
TEXT KMSTempDat[LEN_NUMBER+11] = "";
/* Alter Systemrequester-Windowzeiger (weil umgebogen) */
static APTR OldWindowPtr = NULL;
/* InOut-Fenster-Dimensionen */
BOOL OwnScreen;
/* StdErr Filehandle */
BPTR StdErr = NULL;
/* PC-Font */
BOOL UsePCFont = FALSE;
struct TextFont *PCTextFont = NULL;
struct TextAttr PCFont =
{
"IBM.font",
8,
FS_NORMAL,
FPF_DISKFONT
};
/* Dummy-User */
struct UserNode DummyUser;
/*******************************************
* Öffnen der Libraries u.a. *
*******************************************
* I: --- *
* O: Fehlercode *
*******************************************/
/// "OpenLib"
UBYTE OpenLib(VOID)
{
StdErr = (BPTR)Open("CON:0/10//100/KMSPort Error/CLOSE/AUTO/WAIT", MODE_OLDFILE);
if (SysBase->LibNode.lib_Version < 37)
{
Error("FATAL ERROR: [OpenLib] AmigaOS >=2.04 needed");
return 1;
}
DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", 33);
if (!DiskfontBase)
{
Error("FATAL ERROR: [OpenLib] couldn't OpenLibrary(diskfont.library)");
return 2;
}
if (!(KMS_LC = AllocMem((ULONG)sizeof(struct LocalConfig), MEMF_PUBLIC|MEMF_CLEAR)))
{
Error("FATAL ERROR: [OpenLib] couldn't AllocMem(KMS_LC)");
return 4;
}
/* Command-History-Liste initialisieren */
NewList((struct List *)&KMS_LC->HistoryList);
/* LocalConfig initialisieren */
KMS_LC->Device = DEV_CONSOLE;
KMS_LC->HistCount = 0;
KMS_LC->Cursor = TRUE;
/* Kommando-Parameterliste initialisieren */
UBYTE n;
for(n = 0; n < MAXCMDARGS; n++)
CmdArgV[n] = NULL;
return 0;
}
///
/***************************************
* Client beim Master anmelden *
***************************************
* I: --- *
* O: 0: Ok >0: Fehler *
***************************************/
/// "Identify"
UBYTE Identify(VOID)
{
struct KMSNode *newentry;
UWORD res = 0;
UBYTE count = 0;
/* System-Login */
TEXT varbuff[32] = "";
TEXT pwbuff[32] = "";
GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
GetVar("KMSPWD", pwbuff, sizeof(pwbuff), NULL);
if (!(SysUMSAccount = UMSRLogin(varbuff, "KMS", pwbuff)))
{
Error("FATAL ERROR: [Identify] couldn't log into UMS");
return 1;
}
/* Eventuell Server starten */
if (!FindPort("KMSServer"))
{
TEXT dosbuff[LEN_DOSPATH+1];
STRPTR bindir;
if (bindir = ReadUMSConfigTags(SysUMSAccount, UMSTAG_CfgName, "KMS.BinDir", TAG_DONE))
{
strcpy(dosbuff, bindir);
if (strlen(dosbuff))
if (dosbuff[strlen(dosbuff)-1] != ':' && dosbuff[strlen(dosbuff)-1] != '/')
strcat(dosbuff, "/");
FreeUMSConfig(SysUMSAccount, bindir);
}
else
*dosbuff = '\0';
strcat(dosbuff, "KMSServer >NIL: <NIL:");
SystemTags(dosbuff, SYS_Input, NULL, SYS_Output, NULL, SYS_Asynch, TRUE, TAG_DONE);
}
/* Warten auf Server-Rexx-Port */
count = 0;
while(!FindPort("KMS") && count++ < 15)
Delay(50);
if (!FindPort("KMS"))
{
Error("FATAL ERROR: [Identify] Port KMS not found");
return 1;
}
/* KMSBase besorgen und anmelden */
if (!(KMSBase = (struct KMSBase *)FindSemaphore(KMSBASENAME)))
{
Error("FATAL ERROR: [Identify] KMSBase not found");
return 1;
}
else
ObtainSemaphoreShared(&KMSBase->BaseSem);
/* System ID ermitteln */
TakeMSem(TRUE);
UWORD previd = 0, id = 0;
struct KMSNode *mpoint = KMSBase->MemberList.mlh_Head;
if (mpoint->Node.mln_Succ)
id = mpoint->LCPtr->ID;
while(mpoint->Node.mln_Succ && previd == id - 1)
{
previd = id;
mpoint = mpoint->Node.mln_Succ;
if (mpoint->Node.mln_Succ)
id = mpoint->LCPtr->ID;
}
KMS_LC->ID = previd + 1;
/* neuen MemberList-Eintrag erzeugen */
if (!(newentry = AllocMem((ULONG)sizeof(struct KMSNode), MEMF_PUBLIC|MEMF_CLEAR)))
{
Error("FATAL ERROR: [Identify] couldn't AllocMem(KMSNode)");
return 1;
}
newentry->LCPtr = KMS_LC;
AddTail((struct List *)&KMSBase->MemberList, (struct Node *)newentry);
DropMSem();
/* Rexx-Port-Namen erzeugen */
sprintf(RexxPortName, "KMS.%d", KMS_LC->ID);
/* Rexx-Port einrichten */
if (!(RexxSignal = upRexxPort(RexxPortName, RCL, RexxExtension, &KMSRexxDisp)))
{
Error("FATAL ERROR: [Identify] couldn't upRexxPort(RexxPortName)");
return 1;
}
sprintf(KMSTempDat, "T:KMS_%d.TMP", KMS_LC->ID);
return 0;
}
///
/***************************************
* Öffnen des timer.device *
***************************************
* I: --- *
* O: struct timerequest *Time_Request *
***************************************/
/// "OpenTimer"
UBYTE OpenTimer(VOID)
{
if (!(Timer_Port = (struct MsgPort *)CreatePort(NULL, 0)))
{
Error("FATAL ERROR: [OpenTimer] couldn't CreatePort(Timer_Port)");
return 1;
}
if (!(Time_Request = (struct timerequest *)CreateExtIO(Timer_Port, (ULONG)sizeof(struct timerequest))))
{
Error("FATAL ERROR: [OpenTimer] couldn't CreateExtIO(Time_Request)");
return 2;
}
if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)Time_Request, NULL))
{
Error("FATAL ERROR: [OpenTimer] couldn't OpenDevice(timer.device)");
return 3;
}
TimerSignal = (1L << Time_Request->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
return 0;
}
///
/*********************************
* Öffnen von Screen und Fenster *
*********************************
* I: --- *
* O: Fehlercode *
*********************************/
/// "OpenDisplay"
UBYTE OpenDisplay(VOID)
{
struct Screen *myscreen;
struct Window *mywindow;
sprintf(KMSWinTitle, "%s Port %d", KMSTitle, KMS_LC->ID);
if (!strlen(KMS_LC->WinDim))
{
/* STDIO-Port */
KMS_LC->InHandle = Input();
KMS_LC->OutHandle = Output();
if (!KMS_LC->InHandle || !KMS_LC->OutHandle)
{
Error("FATAL ERROR: [OpenDisplay] IO-Failure");
return 1;
}
}
else
{
/* WINDOW angegeben */
if (OwnScreen)
{
/* KMS-Screen öffnen, wenn nicht schon vorhanden */
myscreen = LockPubScreen(KMSPNAME);
if (!myscreen)
{
/* Screen öffnen */
struct Screen *wbscreen = LockPubScreen(NULL);
if (!wbscreen)
{
Error("FATAL ERROR: [OpenDisplay] couldn't lock default public screen");
return 2;
}
struct DrawInfo *wbdrawinfo = GetScreenDrawInfo(wbscreen);
if (!wbdrawinfo)
{
UnlockPubScreen(NULL, wbscreen);
Error("FATAL ERROR: [OpenDisplay] couldn't GetScreenDrawInfo()");
return 2;
}
ULONG wbmodeid = GetVPModeID(&(wbscreen->ViewPort));
if (wbmodeid == INVALID_ID)
{
FreeScreenDrawInfo(wbscreen, wbdrawinfo);
UnlockPubScreen(NULL, wbscreen);
Error("FATAL ERROR: [OpenDisplay] couldn't GetVPModeID()");
return 2;
}
myscreen = (struct Screen *)
OpenScreenTags(NULL, SA_Title, (ULONG)KMSTitle,
SA_Type, PUBLICSCREEN,
SA_Overscan, OSCAN_TEXT,
SA_DisplayID, wbmodeid,
SA_AutoScroll, TRUE,
SA_PubName, (ULONG)KMSPNAME,
SA_SysFont, 1,
SA_Width, wbscreen->Width,
SA_Height, wbscreen->Height,
SA_Depth, wbdrawinfo->dri_Depth,
SA_Pens, (ULONG)(wbdrawinfo->dri_Pens),
TAG_DONE);
FreeScreenDrawInfo(wbscreen, wbdrawinfo);
UnlockPubScreen(NULL, wbscreen);
if (!myscreen)
{
Error("FATAL ERROR: [OpenDisplay] couldn't OpenScreenTags(myscreen)");
return 3;
}
if (!(PubScreenStatus(myscreen, 0) & 1))
{
Error("FATAL ERROR: [OpenDisplay] Screen couldn't be made public");
return 4;
}
}
else
UnlockPubScreen(NULL, myscreen);
}
/* Fenster gemäß WINDOW-Angabe öffnen */
KMS_LC->InHandle = Open(KMS_LC->WinDim, MODE_OLDFILE);
KMS_LC->OutHandle = KMS_LC->InHandle;
if (!KMS_LC->InHandle || !KMS_LC->OutHandle)
{
Error("FATAL ERROR: [OpenDisplay] IO-Failure");
return 1;
}
if (KMS_LC->Device & DEV_CONSOLE)
{
if (mywindow = GetWindow())
{
SetWindowTitles(mywindow, (STRPTR)-1L, KMSWinTitle);
if (UsePCFont)
{
struct TextFont *old_tf;
PCTextFont = (struct TextFont *)OpenDiskFont(&PCFont);
if (PCTextFont)
{
old_tf = mywindow->RPort->Font;
if (SetFont(mywindow->RPort, PCTextFont))
{
CloseFont(old_tf);
Print("\33c", PF_NOLF|PF_NOBRK);
}
else
{
CloseFont(PCTextFont);
PCTextFont = NULL;
}
}
}
}
}
}
/* DosPacket für Input-Handling */
InputPacket = AllocDosObject(DOS_STDPKT, NULL);
if (!InputPacket)
{
Error("FATAL ERROR: [OpenDisplay] AllocDosObject");
return 5;
}
struct MsgPort *inport = CreatePort(NULL, 0);
if (!inport)
{
Error("FATAL ERROR: [OpenDisplay] CreatePort");
return 5;
}
InputPacket->dp_Link->mn_ReplyPort = inport;
InputPacket->dp_Type = ACTION_WAIT_CHAR;
InputSignal = 1L << inport->mp_SigBit;
/* In RAW:-Modus schalten */
if (IsInteractive(KMS_LC->InHandle))
SetMode(KMS_LC->InHandle, 1);
KMS_LC->RawMode = TRUE;
/* Systemrequester-Windowzeiger umbiegen */
struct Process *myprocess = (struct Process *)FindTask(NULL);
OldWindowPtr = myprocess->pr_WindowPtr;
myprocess->pr_WindowPtr = (APTR)-1L;
return 0;
}
///
/*********************************************
* Schließen aller Libraries, Fenster usw... *
*********************************************
*** I: Exit-Code *
*** O: --- *
*********************************************/
/// "Sense"
VOID Sense(UBYTE exitcode)
{
/* Systemrequester-Windowzeiger wieder zurücksetzen */
if (OldWindowPtr)
{
struct Process *myprocess = (struct Process *)FindTask(NULL);
myprocess->pr_WindowPtr = OldWindowPtr;
}
/* Rexx-Port killen */
dnRexxPort();
/* Diverse Aufräumarbeiten */
if (KMS_LC)
{
/* Command-History-Liste freigeben */
struct HistoryNode *hpoint = KMS_LC->HistoryList.mlh_Head;
while(hpoint->Node.mln_Succ)
{
struct HistoryNode *nexthpoint = hpoint->Node.mln_Succ;
Remove((struct Node *)hpoint);
FreeMem(hpoint, (ULONG)sizeof(struct HistoryNode));
hpoint = nexthpoint;
}
}
if (KMSBase && KMS_LC)
{
/* IO-Kanäle/Fenster schließen, falls WINDOW-Angabe vorhanden war */
if (strlen(KMS_LC->WinDim))
{
if (KMS_LC->InHandle)
Close(KMS_LC->InHandle);
}
else
{
/* In CON: Modus schalten */
if (KMS_LC->InHandle && IsInteractive(KMS_LC->InHandle))
SetMode(KMS_LC->InHandle, 0);
}
if (KMS_LC->SpyHandle)
Close(KMS_LC->SpyHandle);
/* Evt. Screen schließen */
if (KMSBase->MemberList.mlh_Head == KMSBase->MemberList.mlh_TailPred)
{
struct Screen *myscreen;
if (myscreen = LockPubScreen(KMSPNAME))
{
UnlockPubScreen(NULL, myscreen);
Delay(50);
while(!CloseScreen(myscreen))
Delay(50);
}
}
/* Aus der MemberList ausklinken */
TakeMSem(TRUE);
struct KMSNode *mpoint = KMSBase->MemberList.mlh_Head;
if (mpoint->Node.mln_Succ)
{
while(mpoint->Node.mln_Succ && mpoint->LCPtr != KMS_LC)
mpoint = mpoint->Node.mln_Succ;
if (mpoint->Node.mln_Succ && mpoint->LCPtr == KMS_LC)
{
Remove((struct Node *)mpoint);
FreeMem(mpoint, (ULONG)sizeof(struct KMSNode));
}
}
DropMSem();
}
/* Von KMSBase abmelden */
if (KMSBase)
ReleaseSemaphore(&KMSBase->BaseSem);
/* Diverse Aufräumarbeiten */
if (InputPacket)
{
DeletePort(InputPacket->dp_Link->mn_ReplyPort);
FreeDosObject(DOS_STDPKT, InputPacket);
}
if (Time_Request && Time_Request->tr_node.io_Device)
CloseDevice((struct IORequest *)Time_Request);
if (Time_Request)
DeleteExtIO((struct IORequest *)Time_Request);
if (Timer_Port)
DeletePort(Timer_Port);
if (KMS_LC)
FreeMem(KMS_LC, (ULONG)sizeof(struct LocalConfig));
UBYTE n;
for(n = 0; n < MAXCMDARGS; n++)
{
if (CmdArgV[n])
free(CmdArgV[n]);
}
if (strlen(KMSTempDat))
DeleteFile(KMSTempDat);
if (MyUMSAccount)
UMSLogout(MyUMSAccount);
if (SysUMSAccount)
UMSLogout(SysUMSAccount);
if (PCTextFont)
CloseFont(PCTextFont);
if (DiskfontBase)
CloseLibrary(DiskfontBase);
if (StdErr)
Close(StdErr);
exit(exitcode);
}
///
/// "TakeMSem"
VOID TakeMSem(BOOL exclusive)
{
if (exclusive)
ObtainSemaphore(&KMSBase->SaveSem);
else
ObtainSemaphoreShared(&KMSBase->SaveSem);
}
///
/// "DropMSem"
VOID DropMSem(VOID)
{
ReleaseSemaphore(&KMSBase->SaveSem);
}
///